package com.gmail.yesguxun.tumblr.presenter;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.content.ContentValues;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore.Images;

import com.gmail.yesguxun.tumblr.Constant;
import com.gmail.yesguxun.tumblr.content.TrContentObject;
import com.gmail.yesguxun.tumblr.content.TrContentObjectPool;
import com.gmail.yesguxun.tumblr.ui.SettingActivity;
import com.gmail.yesguxun.tumblr.ui.ViewBigPhotoActivity;
import com.gmail.yesguxun.util.EventBusAsync;
import com.gmail.yesguxun.util.EventBusEventObj;
import com.gmail.yesguxun.util.EventBusHandler;
import com.gmail.yesguxun.util.LogFactory;
import com.gmail.yesguxun.util.LogX;

public class TrViewBigPhotoPresenter implements  EventBusHandler{
    
    private ViewBigPhotoActivity mViewBigPhotoActivity = null;
    private TrContentObjectPool mContentObjPool = null;
    private TrContentObject mContentObjShowing = null;
    private Handler mHandler = null;
    
    private static TrViewBigPhotoPresenter mPresenterInstance = null;
    
    private LogX mLog = LogFactory.getLogObject();
    
    public static TrViewBigPhotoPresenter getInstance()
    {
    	if(TrViewBigPhotoPresenter.mPresenterInstance == null)
    	{
    	    TrViewBigPhotoPresenter.mPresenterInstance = new TrViewBigPhotoPresenter();
    	}
    	
    	return TrViewBigPhotoPresenter.mPresenterInstance;
    }
    
    private TrViewBigPhotoPresenter()
    {      
        mContentObjPool = TrContentObjectPool.getPoolInstance();
        mLog.debug("trumblr", "Get ContentPool: " + this.mContentObjPool);           
        
        mHandler = new Handler();        
    }
    
    public void onActivityResume()
    {
    	EventBusAsync.getInstance().registerEventHandler(Constant.EVENT_AUTHORIZATION_COMPLETE, this);
    }
    
    public void onActivityPause()
    {
    	EventBusAsync.getInstance().unRegisterEventHandlerForOneEvent(Constant.EVENT_AUTHORIZATION_COMPLETE, this);
    }
    
    public void onActivityStop()
    {
    	EventBusAsync.getInstance().unRegisterEventHandlerForOneEvent(Constant.EVENT_FIRST_CONTENT_ADDED_TO_POOL, this);
        EventBusAsync.getInstance().unRegisterEventHandlerForOneEvent(Constant.EVENT_NEW_CONTENT_DOWNLOAD_FINISHED, this);
    }
    
    public void onActivityStart()  
    {        
    	mLog.debug("tumblr", "presenter onStart " + this);
    	
    	EventBusAsync.getInstance().registerEventHandler(Constant.EVENT_FIRST_CONTENT_ADDED_TO_POOL, this);
        EventBusAsync.getInstance().registerEventHandler(Constant.EVENT_NEW_CONTENT_DOWNLOAD_FINISHED, this);
    	
    	if(this.mContentObjPool.getContentCurrent() != null)
    	{
            setContentToView(this.mContentObjPool.getContentCurrent());
    	}
    	else
    	{
    		this.refreshContent();
    	}
    }
    
    public void bind(ViewBigPhotoActivity viewBigPhotoActivity)
    {
    	mViewBigPhotoActivity = viewBigPhotoActivity;
    }
    
   
    public void slideRight()
    {
    	mLog.debug("tumblr", "slideRight");
        TrContentObject obj = this.mContentObjPool.getPrevious();
        setContentToView(obj);
    }
    
   
    public void slideLeft()
    {
    	mLog.debug("tumblr", "slideLeft");
        TrContentObject obj = this.mContentObjPool.getNext();
        checkGetMoreData();
        setContentToView(obj);
    }
    
    private void checkGetMoreData()
    {
        int count = mContentObjPool.getContentCount();
        int numOneTimeGet = Integer.parseInt(Constant.API_PARAM_LIMIT_VALUE);
                        
        // TODO: we could send out too many refreshPoolAsync commands...
        if(( count - mContentObjPool.getCursor() ) < numOneTimeGet/2 )
        {
            ((TrContentObjectPool)mContentObjPool).refreshPoolAsync();          
        }
    }
        
           
    private void setContentToView(TrContentObject obj)
    {
        if(obj == null)
        {
        	mLog.debug("tumblr", "setContentToView Null object");
        	//this.mViewBigPhotoActivity.onFailedToSlideNext();
            return;
        }
        
        mContentObjShowing = obj;
        
        if(obj.localCopyExist())
        {
            String picUri = obj.getURI();
            mLog.debug("tumblr", "setContentToView url " + picUri);
            mViewBigPhotoActivity.setContentUri(picUri);
        }
        else
        {
            mViewBigPhotoActivity.setContentUri(null);
        }
        setContentInfoOffset();
    }

    @Override
    public void onEvent(EventBusEventObj eventObj) {
        
        if(eventObj.getEventType().equals(Constant.EVENT_FIRST_CONTENT_ADDED_TO_POOL))
        {
            mLog.debug("tumblr", "Processing event:" + Constant.EVENT_FIRST_CONTENT_ADDED_TO_POOL);
            if(this.mContentObjShowing == null)
            {
                this.mHandler.post(new Runnable(){                    
                    @Override
                    public void run() {
                        slideLeft();                        
                    }
                });                
            }
        }              
        else if(eventObj.getEventType().equals(Constant.EVENT_NEW_CONTENT_DOWNLOAD_FINISHED))
        {                        
            final TrContentObject trContent = (TrContentObject)eventObj.getEventData();
            mLog.debug("tumblr", "Processing event:" + Constant.EVENT_NEW_CONTENT_DOWNLOAD_FINISHED + " id:" + trContent.getID());
            
            this.mHandler.post(new Runnable(){                    
                @Override
                public void run() {
                	setContentInfoOffset();  
                	contentReady(trContent.getID());
                }
            });                
        }        
        else if(eventObj.getEventType().equals(Constant.EVENT_AUTHORIZATION_COMPLETE))
        {
        	Boolean result = (Boolean)eventObj.getEventData();
			mLog.debug("tumblr", "Processing event:" + Constant.EVENT_AUTHORIZATION_COMPLETE);
            if(result.booleanValue() == false)
            {
                this.mHandler.post(new Runnable(){                    
                    @Override
                    public void run() {
                    	settingConfig();                        
                    }
                });                
            }
        }
    }
    
    public void setContentInfoOffset()
    {
    	this.mViewBigPhotoActivity.setContentInfoOffset(mContentObjPool.getCursor(), mContentObjPool.getContentCount());
    }

    private void contentReady(int id)
    {
        //now we finished the download
        if(this.mContentObjShowing == null || this.mContentObjShowing.getID() == id)
        {
            //set this again to update
            this.setContentToView(this.mContentObjShowing);
        }
    }
    
	public void settingConfig() {
		this.mContentObjPool.clearAllContent();
		
		mLog.debug("tumblr", "Starting SettingActivity");
		Intent myIntent = new Intent(mViewBigPhotoActivity, SettingActivity.class);
		mViewBigPhotoActivity.startActivity(myIntent);
		
		mViewBigPhotoActivity.finish();
	}


	public void refreshContent() {
		this.mContentObjPool.clearAllContent();
		this.mContentObjShowing = null;
		slideLeft();   
	}
	
	public boolean saveContent()
	{
	    boolean saveResult = false;
	    
	    String filePathSrc = this.mContentObjShowing.getURI();
	    
	    File pathDes = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES );
	    File filePathDes = new File(pathDes, this.mContentObjShowing.getTitle());
	    
	    try {
	        pathDes.mkdirs();
            java.io.FileInputStream fileStreamIn = new java.io.FileInputStream(new File(filePathSrc));
            FileOutputStream fileStreamOut = new FileOutputStream(filePathDes);
            
             
            int bufferSize = 1024 * 3;
            byte[] data = new byte[bufferSize];
            int x=0;
      
            while((x=fileStreamIn.read(data,0,bufferSize))>=0)
            {
                fileStreamOut.write(data,0,x);
            }
            
            fileStreamIn.close();
            fileStreamOut.close();
            
            MediaScannerConnection.scanFile(mViewBigPhotoActivity, new String[] { filePathDes.toString() }, null,null);
            
            saveResult = true;
        }catch (IOException e) {
            saveResult = false;
        }
	    
	    return saveResult;
	}
	

    public void likeContent() {
        this.mContentObjPool.likeContent(this.mContentObjShowing);
    }
}
